package org.chartsy.cci;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Stroke;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import org.chartsy.main.ChartFrame;
import org.chartsy.main.chart.Indicator;
import org.chartsy.main.data.DataItem;
import org.chartsy.main.data.Dataset;
import org.chartsy.main.utils.DefaultPainter;
import org.chartsy.main.utils.Range;
import org.chartsy.main.utils.SerialVersion;
import org.openide.nodes.AbstractNode;
/**
*
* @author viorel.gheba
*/
public class CCI
extends Indicator
{
private static final long serialVersionUID = SerialVersion.APPVERSION;
public static final String CCI = "cci";
private IndicatorProperties properties;
public CCI()
{
super();
properties = new IndicatorProperties();
}
public String getName()
{ return "CCI"; }
public String getLabel()
{ return properties.getLabel() + "(" + properties.getPeriod() + ")"; }
public String getPaintedLabel(ChartFrame cf)
{ return getLabel(); }
public Indicator newInstance()
{ return new CCI(); }
public LinkedHashMap getHTML(ChartFrame cf, int i)
{
LinkedHashMap ht = new LinkedHashMap();
DecimalFormat df = new DecimalFormat("#,##0.00");
double[] values = getValues(cf, i);
String[] labels = {"CCI:"};
ht.put(getLabel(), " ");
if (values.length > 0) {
Color[] colors = getColors();
for (int j = 0; j < values.length; j++) {
ht.put(getFontHTML(colors[j], labels[j]),
getFontHTML(colors[j], df.format(values[j])));
}
}
return ht;
}
public void paint(Graphics2D g, ChartFrame cf, Rectangle bounds)
{
Dataset d = visibleDataset(cf, CCI);
if (d != null)
{
if (maximized)
{
Range range = getRange(cf);
DefaultPainter.line(g, cf, range, bounds, d, properties.getColor(), properties.getStroke()); // paint line
if (properties.getInsideVisibility())
{
paintFill(g, cf, d, bounds, range, properties.getInsideTransparentColor(), -100d, range.getLowerBound() - 10, false); // paint fill
paintFill(g, cf, d, bounds, range, properties.getInsideTransparentColor(), 100d, range.getUpperBound() + 10, true); // paint fill
}
}
}
}
public void calculate()
{
Dataset initial = getDataset();
if (initial != null && !initial.isEmpty())
{
int period = properties.getPeriod();
Dataset d = getDataset(initial, period);
addDataset(CCI, d);
}
}
public boolean hasZeroLine()
{ return true; }
public boolean getZeroLineVisibility()
{ return properties.getZeroLineVisibility(); }
public Color getZeroLineColor()
{ return properties.getZeroLineColor(); }
public Stroke getZeroLineStroke()
{ return properties.getZeroLineStroke(); }
public boolean hasDelimiters()
{ return true; }
public boolean getDelimitersVisibility()
{ return true; }
public double[] getDelimitersValues()
{ return new double[] {-200.0d, -100.0d, 100.0d, 200.0d}; }
public Color getDelimitersColor()
{ return properties.getZeroLineColor(); }
public Stroke getDelimitersStroke()
{ return properties.getZeroLineStroke(); }
public Color[] getColors()
{ return new Color[] {properties.getColor()}; }
public double[] getValues(ChartFrame cf)
{
Dataset d = visibleDataset(cf, CCI);
int i = d.getLastIndex();
if (d.getDataItem(i) != null)
return new double[] {d.getCloseAt(i)};
return new double[] {0};
}
public double[] getValues(ChartFrame cf, int i)
{
Dataset d = visibleDataset(cf, CCI);
if (d.getDataItem(i) != null)
return new double[] {d.getCloseAt(i)};
return new double[] {0};
}
public boolean getMarkerVisibility()
{ return properties.getMarker(); }
public AbstractNode getNode()
{ return new IndicatorNode(properties); }
@Override
public Double[] getPriceValues(ChartFrame cf)
{
List<Double> list = new ArrayList<Double>();
Range range = getRange(cf);
list.add(new Double(-200));
list.add(new Double(-100));
list.add(new Double(100));
list.add(new Double(200));
if (range.getUpperBound() >= 300)
list.add(new Double(300));
if (range.getLowerBound() <= -300)
list.add(new Double(-300));
return list.toArray(new Double[list.size()]);
}
private Dataset getDataset(final Dataset initial, final int period) {
int count = initial.getItemsCount();
Dataset d = Dataset.EMPTY(count);
for (int i = period - 1; i < count; i++)
{
double TP = (initial.getHighAt(i) + initial.getLowAt(i) + initial.getCloseAt(i)) / 3;
double TPMA = 0D;
for (int j = i - period + 1; j <= i; j++)
TPMA += ((initial.getHighAt(j) + initial.getLowAt(j) + initial.getCloseAt(j)) / 3);
TPMA /= (double)period;
double MD = 0D;
for (int j = i - period + 1; j <= i; j++)
MD += Math.abs((initial.getHighAt(j) + initial.getLowAt(j) + initial.getCloseAt(j)) / 3 - TPMA);
MD /= (double)period;
double close = (TP - TPMA)/(0.015D * MD);
d.setDataItem(i, new DataItem(initial.getTimeAt(i), close));
}
return d;
}
}